package ltg.ibutton.core.wrappers;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.dalsemi.onewire.OneWireException;
import com.dalsemi.onewire.adapter.OneWireIOException;
import com.dalsemi.onewire.adapter.PDKAdapterUSB;

/**
 * @author Francesco Novellis
 *
 */
public class OneWireWrapper extends Wrapper {
	
	private PDKAdapterUSB pdk = new PDKAdapterUSB();
	
	private OneWireWrapper() {};
	
	private static final Wrapper INSTANCE = new OneWireWrapper();

	public static Wrapper getInstance() {
		return INSTANCE;
	}
	
	public synchronized ArrayList<String> getAll() {
		int i = 1;
		ArrayList<String> deviceList = new ArrayList<String>();
		try {
			pdk.beginExclusive(true);
			while (pdk.selectPort("USB" + i) && pdk.adapterDetected()) {
				boolean next = pdk.findFirstDevice();
				while (next) {
					deviceList.add(pdk.getAddressAsString());
					next = pdk.findNextDevice();
				}
				//System.out.println(pdk.getPortName() + ": " + pdk.getAddressAsString()); /**************/
				i++;
				pdk.freePort();
			}
			pdk.endExclusive();
		} catch (OneWireIOException e) {
			e.printStackTrace();
		} catch (OneWireException e) {
			e.printStackTrace();
		}
		return deviceList;
	}
	
	public synchronized ArrayList<String> getReaders() {
		int i = 1;
		ArrayList<String> readersList = new ArrayList<String>();
		try {
			pdk.beginExclusive(true);
			while (pdk.selectPort("USB" + i) && pdk.adapterDetected()) {
				pdk.findFirstDevice();
				Pattern p = Pattern.compile("(81)$");
				Matcher m = p.matcher(pdk.getAddressAsString());
				while (!m.find()) {
					pdk.findNextDevice();
					m = p.matcher(pdk.getAddressAsString());
				}
				readersList.add(pdk.getAddressAsString());
				//System.out.println(pdk.getPortName() + ": " + pdk.getAddressAsString()); /**************/
				i++;
				pdk.freePort();
			}
			pdk.endExclusive();
		} catch (OneWireIOException e) {
			e.printStackTrace();
		} catch (OneWireException e) {
			e.printStackTrace();
		}
		return readersList;
	}
	
	public synchronized ArrayList<String> getButtons() {
		int i = 1;
		ArrayList<String> buttonsList = new ArrayList<String>();
		try {
			pdk.beginExclusive(true);
			while (pdk.selectPort("USB" + i) && pdk.adapterDetected()) {
				pdk.findFirstDevice();
				Pattern p = Pattern.compile("(01)$");
				Matcher m = p.matcher(pdk.getAddressAsString());
				while (!m.find()) {
					pdk.findNextDevice();
					m = p.matcher(pdk.getAddressAsString());
				}
				buttonsList.add(pdk.getAddressAsString());
				//System.out.println(pdk.getPortName() + ": " + pdk.getAddressAsString()); /**************/
				i++;
				pdk.freePort();
			}
			pdk.endExclusive();
		} catch (OneWireIOException e) {
			e.printStackTrace();
		} catch (OneWireException e) {
			e.printStackTrace();
		}
		return buttonsList;
	}
	
	public synchronized ArrayList<String> getButtonsFromPort(String portName) {
		ArrayList<String> buttonsList = new ArrayList<String>();
		try {
			pdk.beginExclusive(true);
			if (pdk.selectPort(portName) && pdk.adapterDetected()) {
				pdk.findFirstDevice();
				Pattern p = Pattern.compile("(01)$");
				Matcher m;
				do {
					m = p.matcher(pdk.getAddressAsString());
					if (m.find())
						buttonsList.add(pdk.getAddressAsString());
				} while (pdk.findNextDevice());
			}
			pdk.freePort();
			pdk.endExclusive();
		} catch (OneWireIOException e) {
			e.printStackTrace();
		} catch (OneWireException e) {
			e.printStackTrace();
		}
		return buttonsList;
	}
}
